package com.dupt.web.controller.material;

import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.dupt.system.domain.*;
import com.dupt.system.domain.param.MaterialBillMainParam;
import com.dupt.system.domain.param.MaterialBillParam;
import com.dupt.system.domain.param.MaterialParam;
import com.dupt.system.domain.vo.MaterialBillDetialVo;
import com.dupt.system.domain.vo.MaterialBillMainVo;
import com.dupt.system.domain.vo.MaterialBillVo;
import com.dupt.system.domain.vo.MaterialDetialVo;
import com.dupt.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dupt.common.annotation.Log;
import com.dupt.common.core.controller.BaseController;
import com.dupt.common.core.domain.AjaxResult;
import com.dupt.common.enums.BusinessType;
import com.dupt.common.utils.poi.ExcelUtil;
import com.dupt.common.core.page.TableDataInfo;

/**
 * 物料清单明细Controller
 * 
 * @author zhuanyu.sun
 * @date 2025-06-15
 */
@RestController
@RequestMapping("/material/bill")
public class MaterialBillController extends BaseController
{
    @Autowired
    private IMaterialBillDetialService materialBillDetialService;
    @Autowired
    private IMaterialBillMainService materialBillMainService;
    @Autowired
    private IMaterialDetialService materialDetialService;

    /**
     * 查询物料清单明细列表
     */
    @PreAuthorize("@ss.hasPermi('material:bill:list')")
    @GetMapping("/list")
    public TableDataInfo list(MaterialBillMainParam materialBillMainParam)
    {
        startPage();
        //获取主表所有信息
        List<MaterialBillMainVo> list = materialBillMainService.selectMaterialBillMainList(materialBillMainParam);
        if(list.size()==0)
            return getDataTable(list);
        List<MaterialBillVo> billVoList = new ArrayList<>(list.size());

        // 获取所有的ID
        List<String> mainIds = list.stream()
                .map(MaterialBillMainVo::getMaterialBillMainId)
                .collect(Collectors.toList());
        Map<String, List<MaterialBillDetialVo>> detailsMap = materialBillDetialService
                .batchSelectMaterialBillDetialByMainIds(mainIds)
                .stream()
                .collect(Collectors.groupingBy(MaterialBillDetialVo::getMaterialBillMainId));

        // 使用并行流处理（根据数据量选择）
        list.parallelStream().forEach(item -> {
            MaterialBillVo vo = new MaterialBillVo();
            BeanUtils.copyProperties(item, vo);

            // 从预加载的Map中获取明细列表
            List<MaterialBillDetialVo> detailList = detailsMap.getOrDefault(
                    item.getMaterialBillMainId(),
                    Collections.emptyList()
            );
            vo.setMaterialBillDetialVoList(detailList);

            // 使用同步块保证线程安全
            synchronized(billVoList) {
                billVoList.add(vo);
            }
        });
        return getDataTable(billVoList);
    }

    /**
     * 导出物料清单明细列表
     */
    @PreAuthorize("@ss.hasPermi('material:bill:export')")
    @Log(title = "物料清单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, MaterialBillDetial materialBillDetial)
    {
        List<MaterialBillDetial> list = materialBillDetialService.selectMaterialBillDetialList(materialBillDetial);
        ExcelUtil<MaterialBillDetial> util = new ExcelUtil<MaterialBillDetial>(MaterialBillDetial.class);
        util.exportExcel(response, list, "物料清单明细数据");
    }

    /**
     *
     * @param materialBillMainId 物料清单主表ID
     * @return
     */
//    @PreAuthorize("@ss.hasPermi('material:bill:query')")
//    @GetMapping(value = "/{materialBillMainId}")
//    public AjaxResult getInfo(@PathVariable("materialBillMainId") String materialBillMainId)
//    {
//        return success(materialBillDetialService.selectMaterialBillDetialByMaterialBillMainId(materialBillMainId));
//    }

    /**
     *
     * @param materialBillMainId 物料清单主表ID
     * @return
     */
    @PreAuthorize("@ss.hasPermi('material:bill:query')")
    @GetMapping(value = "/{materialBillMainId}")
    public AjaxResult getInfo(@PathVariable("materialBillMainId") String materialBillMainId)
    {
        MaterialBillVo vo = new MaterialBillVo();
        //1.根据物料清单主表ID查询物料主表信息
        MaterialBillMain billMain = materialBillMainService.selectMaterialBillMainByMaterialBillMainId(materialBillMainId);
        BeanUtils.copyProperties(billMain,vo);
        //2. 根据物料清单主表ID查询物料清单明细表信息
        List<MaterialBillDetialVo> billDetialVoList = materialBillDetialService.selectMaterialBillDetialByMaterialBillMainId(materialBillMainId);
        vo.setMaterialBillDetialVoList(billDetialVoList);
        return success(vo);
    }

    /**
     * 新增物料清单明细
     */
    @PreAuthorize("@ss.hasPermi('material:bill:add')")
    @Log(title = "物料清单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MaterialBillMainParam materialBillMainParam)
    {
        //1.根据名称、规格型号、适用温度查询物料明细表是否存在，存在则使用，不存在创建后在使用
        MaterialDetial materialDetial = new MaterialDetial();
        BeanUtils.copyProperties(materialBillMainParam,materialDetial);
        List<MaterialDetialVo> detialList = materialDetialService.selectMaterialDetialList(materialDetial);
        //不存在，则创建
//        if(detialList.size()==0){
//            materialDetial.setAmount(0L);
//            materialDetial.setIsSetSerial("1");
//            List<MaterialParam> materialParamList = new ArrayList<>();
//            MaterialParam materialParam = new MaterialParam();
//            BeanUtils.copyProperties(materialBillMainParam,materialParam);
//            materialParamList.add(materialParam);
//            materialDetialService.insertMaterial(materialParamList);
//            //根据物料查询
//            detialList = materialDetialService.selectMaterialDetialList(materialDetial);
//        }
//        //存在，根据内码查询物料采集表中的ID
//        MaterialCollect materialCollect = materialCollectService.selectMaterialCollectByMaterialInnerCode(detialList.get(0).getMaterialInnerCode());
//        //根据物料ID查询主表中是否存在
//        MaterialBillMain billMain = materialBillMainService.selectMaterialBillMainByMaterialCollectId(materialCollect.getMaterialCollectId());
//        if(billMain!=null){
//            return error("该父类物料已存在。");
//        }
//        //3. 新增主表信息
//        MaterialBillMain main = new MaterialBillMain();
//        main.setMaterialBillMainId(UUID.randomUUID().toString());
//        main.setMaterialCollectId(materialCollect.getMaterialCollectId());
//        materialBillMainService.insertMaterialBillMain(main);

        //4. 新增子表信息
//        List<MaterialBillDetial> materialBillDetials = materialBillMainParam.getMaterialBillDetials();
//        materialBillDetialService.insertMaterialBillDetial(materialBillDetials,main.getMaterialBillMainId());
        return success();
    }

    /**
     * 修改物料清单明细
     */
    @PreAuthorize("@ss.hasPermi('material:bill:edit')")
    @Log(title = "物料清单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MaterialBillParam materialBillParam)
    {
        //根据主表删除对应的明细表
        materialBillDetialService.deleteMaterialBillDetialByMaterialBillMainId(materialBillParam.getMaterialBillMainId());
        //2. 批量插入明细表
        List<MaterialBillDetial> materialBillDetials = materialBillParam.getMaterialBillDetials();
        materialBillDetialService.insertMaterialBillDetial(materialBillDetials,materialBillParam.getMaterialBillMainId());
        return success();
    }

    /**
     * 删除物料清单明细
     */
    @PreAuthorize("@ss.hasPermi('material:bill:remove')")
    @Log(title = "物料清单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{materialBillMainIds}")
    public AjaxResult remove(@PathVariable String[] materialBillMainIds)
    {
        //根据主表删除明细表相关数据
        materialBillDetialService.deleteMaterialBillDetialByMaterialBillMainIds(materialBillMainIds);
        //根据主表ID删除主表相关数据
        materialBillMainService.deleteMaterialBillMainByMaterialBillMainIds(materialBillMainIds);
        return success();
    }
}
